package shoot;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.nio.channels.NonReadableChannelException;
import java.sql.Time;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 主类
 * @author pc
 *
 */
public class World  extends JPanel{
	
	public static final int WIDTH=400;
	public static final int HEIGHT=700;
	//游戏的三种状态
	public static final int START=1;
	public static final int RUNNING=2;
	public static final int PAUSE=3;
	public static final int OVER=4;
	public int status=START;
	//状态图片
	private static BufferedImage startImage;
	private static BufferedImage pauseImage;
	private static BufferedImage overImage;
	
	static {
		startImage=FlyingObject.loadImage("start.png");
		pauseImage=FlyingObject.loadImage("pause.png");
		overImage=FlyingObject.loadImage("gameover.png");
	}
	

	//创建对象
	FlyingObject[] enemys= {};
	Bullt[] bullts= {};
	HeroAirPlane heroAirPlane=new HeroAirPlane();
	Sky sky=new Sky();

	
	@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		sky.paintObject(g);
		heroAirPlane.paintObject(g);
		//画子弹
		for (int i = 0; i < bullts.length; i++) {
			bullts[i].paintObject(g);
		}
		for (int i = 0; i < enemys.length; i++) {
			enemys[i].paintObject(g);
		}
		//显示 分数和火力值
		g.drawString("得分："+score, 15, 20);
		g.drawString("生命值："+heroAirPlane.getLift(), 15, 50);
		g.drawString("火力值："+heroAirPlane.getDoubleFire(), 15, 35);
		
		//画游戏状态
		switch (status) {
			case START:
				g.drawImage(startImage,0,0,null);
				break;
			case PAUSE:
				g.drawImage(pauseImage,0,0,null);
				break;
			case OVER:
				g.drawImage(overImage,0,0,null);
				break;
			default:
				break;
		}
		
	}
	
	/**
	 * 按照一定比例生成敌人对象
	 * @return
	 */
	public FlyingObject nextOne() {
		Random random=new Random();
		int type=random.nextInt(20);
		if(type<5) {
			return new Bee();
		}else if (type<12) {
			return new BigAirPlane();
		}else {
			return new AirPlane();
		}
	}
	
	/**
	 * 敌人入场
	 */
	int enemyIndex=0;
	public void enemyAction() {
		enemyIndex++; //这个函数没10ms +1
		if(enemyIndex % 40==0) {
			//没 400ms 生成一个敌机
			FlyingObject object=nextOne();
			//扩容
			enemys=Arrays.copyOf(enemys, enemys.length+1);
			//填充
			enemys[enemys.length-1]=object;
		}
	}
	
	/**
	 * 子弹入场
	 */
	int shootIndex=0;
	public void shootAction() {
		shootIndex++;
		if(shootIndex % 30==0) {
			Bullt[] bullt=heroAirPlane.shoot();
			bullts=Arrays.copyOf(bullts, bullts.length+bullt.length);
			//增加的子弹的个数不一定
			System.arraycopy(bullt, 0, bullts, bullts.length-bullt.length, bullt.length);
		}
	}
	
	
	/**
	 * 飞行物移动
	 */
	public void stepAction() {
		sky.step();
		for (int i = 0; i < bullts.length; i++) {
			bullts[i].step();
		}
		for (int i = 0; i < enemys.length; i++) {
			enemys[i].step();
		}
	}
	
	/**
	 * 判断飞行物及子弹的越界
	 */
	public void outOfBoundsAction() {
		int index=0;
		//活着的飞行物
		FlyingObject[]  enemyLives=new FlyingObject[enemys.length];
		for (int i = 0; i < enemys.length; i++) {
			//如果没有越界和未被移除是飞行物
			if(!enemys[i].outOfBound() && !enemys[i].isRemove() ) {
				enemyLives[index]=enemys[i];
				index++;
			}
		}
		//从新创建敌人对象
		enemys=Arrays.copyOf(enemyLives, index);
		
		//子弹越界则删除
		index=0;
		Bullt[] bulltLives=new Bullt[bullts.length];
		for (int i = 0; i < bullts.length; i++) {
			if(!bullts[i].outOfBound()) {
				bulltLives[index]=bullts[i];
				index++;
			}
		}
		//重新赋值子弹对象
		bullts=Arrays.copyOf(bulltLives, index);
	}
	
	/*
	 * 子弹和敌机碰撞
	 */
	//得分
	int score=0;
	public void enemyBangAction() {
		for (int i = 0; i < bullts.length; i++) {
			FlyingObject  b = bullts[i];
			for (int j = 0; j < enemys.length; j++) {
				FlyingObject e = enemys[j];
				//飞行物 活着 且碰撞
				if(b.isLift() && e.isLift() && b.hit(e)) {
					b.goDie();
					e.goDie();
					//判断是的敌机,加分
					if(e instanceof Enemy) {
						//强转类型
						Enemy aEnemy=(Enemy)e;
						score+=aEnemy.getScore();
					}
					//判断小蜜蜂 加命
					if (e instanceof Award) {
						Award aAward=(Award)e;
						int type=aAward.getAwardType();
						System.out.println(type);
						switch (type) {
							case Award.DOUBLE_FIRE:
								//增加火力值
								heroAirPlane.addDoubleFire();
								break;
							case Award.LIFT:
								//增加命
								heroAirPlane.addLift();
								break;
							default:
								break;
						}
					}
					
					
				}
			}
		}
	}
	
	/**
	 * 英雄机和敌机碰撞
	 */
	public void heroBangAction() {
		for (int i = 0; i < enemys.length; i++) {
			FlyingObject e =enemys[i];
			if(e.isLift() && e.hit(heroAirPlane)) {
				e.goDie();
				//英雄机减命
				heroAirPlane.delLift();
				heroAirPlane.clearDoubleFire();
			}
		}
	}
	
	/*
	 * 检查游戏是否结束
	 */
	public void checkGameOver() {
		if(heroAirPlane.getLift()<=0) {
			status=OVER;
		}
	}
	
	
	public void action() {
		MouseAdapter adapter=new MouseAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				//英雄机跟随鼠标移动
				heroAirPlane.moveTo(e.getX(), e.getY());
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				//点击事件
				switch (status) {
					case START:
						status=RUNNING;
						break;
					case RUNNING:
						status=PAUSE;
						break;
					case PAUSE:
						status=RUNNING;
						break;
					case OVER:
						score=0;
						sky =new Sky();
						heroAirPlane=new HeroAirPlane();
						bullts=new Bullt[0];
						enemys=new FlyingObject[0];
						status=START;
						break;
					default:
						break;
				}
			}
			
			//鼠标移出的时候
			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
				if (status==RUNNING) {
					status=PAUSE;	
				}
			}
			
		};
		//监听
		addMouseListener(adapter);
		addMouseMotionListener(adapter);
		
		
		//定时任务
		Timer timer =new Timer();
		//每10毫秒执行一次
		int intavel=10;
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if (status==RUNNING) {
					enemyAction();	
					shootAction();
					//对象生成后再移动
					stepAction();
					enemyBangAction();
					heroBangAction();
					outOfBoundsAction();
					checkGameOver();
				}
				//重画对象
				repaint();
			}
		}, intavel,intavel);
	}
	
	
	public static void main(String[] args) {
		//画窗口
		JFrame jFrame=new JFrame();
		World world=new World();
		world.action();
		jFrame.add(world);
		jFrame.setSize(World.WIDTH,world.HEIGHT);
		jFrame.setLocationRelativeTo(null);
		jFrame.setVisible(true);		
	}
	
	
}
